#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2017-09-21 17:21:57
# @Author  : WUQINGLONG
# @Contact : 1603763721@qq.com

# =======================================
# 优美胜于丑陋（Python 以编写优美的代码为目标）
# 明了胜于晦涩（优美的代码应当是明了的，命名规范，风格相似）
# 简洁胜于复杂（优美的代码应当是简洁的，不要有复杂的内部实现）
# 复杂胜于凌乱（如果复杂不可避免，那代码间也不能有难懂的关系，要保持接口简洁）
# 扁平胜于嵌套（优美的代码应当是扁平的，不能有太多的嵌套）
# 间隔胜于紧凑（优美的代码有适当的间隔，不要奢望一行代码解决问题）
# 可读性很重要（优美的代码是可读的）
# =======================================

"""
功能描述：
    1.发起网络请求，获取数据
"""

import logging
import simplejson as json
import traceback
import time
import re
import sys

VERSION2 = (sys.version_info[0] == 2)

if VERSION2:
    import httplib
    import urlparse
else:
    import urllib.parse as urlparse
    import http.client as httplib


# 发送http(s)请求，返回json，重试5次
def request_json(url, method='GET', body=None, headers=None, timeout=600, times=5):
    data = request(url, method, body, headers, timeout, times)
    try:
        return json_to_obj(data)
    except Exception:
        logging.error('parse json[%s] error: %s' % (data, traceback.format_exc()))


def request(url, method='GET', body=None, headers=None, timeout=600, times=5):
    """http(s)请求工具类"""
    url_parts = urlparse.urlsplit(url)
    if url_parts.scheme == 'https':
        conn = httplib.HTTPSConnection(url_parts.netloc, timeout=timeout)
    else:
        conn = httplib.HTTPConnection(url_parts.netloc, timeout=timeout)
    if body is not None:
        method = 'POST'
    if headers is None:
        headers = {}
    try:
        path = url_parts.path
        if url_parts.query:
            path = path + '?' + url_parts.query
        conn.request(method, path, body, headers)
        resp = conn.getresponse()
        bytes_data = resp.read()
        logging.info('url: %s, headers: %s, times: %d, result: %s' % (url, headers, times, bytes_data))
        return bytes_data
    except Exception:
        logging.error('request[%s] error: %s' % (url,
                                                 traceback.format_exc()))
        if times > 0:
            time.sleep(5)
            return request_json(url, method, body, headers, timeout, times - 1)


# json转换处理
def json_to_obj(json_str):
    if not json_str:
        return
    try:
        # 处理json最后多一个“,”问题
        json_str = re.sub(r',(?=[\}\]])', '', json_str)
        # 处理json中字符串前多一个“\”，但又不是换行、回车等转义的情况
        json_str = re.sub(r'''\\(?=[^abfnrtv"])''', '', json_str)
        json_str = re.sub(r'''"/[^"]*\"''', '""', json_str)
        # 过滤特殊字符串
        json_str = json_str.replace('varwosoadconfig={cid:"23130",aid:"1036;\f\t\n', '')
        return json.loads(json_str, 'utf-8', strict=False)
    except Exception:
        print('convert json[%s] error: %s' % (json_str, traceback.format_exc()))


if __name__ == '__main__':
    print(request('http://www.baidu.com/'))
